﻿//using System;
//using System.Collections;
//using System.Collections.Generic;
//using System.Threading;
//using ArgusPCLib;

//namespace ArgusPCLib.Threading
//{
//	public static class Parallelization
//	{
//		public delegate void ForEachBody<T>(T item, ThreadState threadState);
//		public delegate void ForBody(int index, ThreadState threadState);
//		public delegate IEnumerable<TaskBody> TaskBody(ThreadState threadState);

//		public delegate void ProgressChangedHandler(double progress);
//		public delegate void ProcessTasksProgressHandler(int tasksProcessed, int tasksToProcess);

//		public static void ForEach<T>(IEnumerable collection, ForEachBody<T> body, int numberOfThreads, ThreadState threadState, ProgressChangedHandler progressChanged)
//		{
//			List<TaskHandler> tasks = new List<TaskHandler>();
//			foreach (T item in collection)
//			{
//				tasks.Add(new TaskHandler((tState) =>
//					{
//						body(item, tState);
//						return null;
//					}));
//			}
//			ProcessTasksProgressHandler progress = null;
//			if (progressChanged != null)
//			{
//				progress = new ProcessTasksProgressHandler((finished, total) =>
//					 {
//						 progressChanged((double)finished / (finished + total));
//					 });
//			}
//			Parallelization.ProcessTasks(tasks, numberOfThreads, threadState, progress);
//		}

//		public static void ForEach<T>(IEnumerable collection, ForEachBody<T> body, ThreadState threadState, ProgressChangedHandler progressChanged)
//		{
//			Parallelization.ForEach<T>(collection, body, System.Environment.ProcessorCount, threadState, progressChanged);
//		}

//		public static void ForEach<T>(IEnumerable collection, ForEachBody<T> body, ThreadState threadState)
//		{
//			Parallelization.ForEach<T>(collection, body, threadState, null);
//		}

//		public static void ForEach<T>(IEnumerable collection, ForEachBody<T> body)
//		{
//			ThreadState threadState = new ThreadState();
//			Parallelization.ForEach<T>(collection, body, threadState, null);
//		}

//		public static void For(int count, ForBody body, int numberOfThreads, ThreadState threadState, ProgressChangedHandler progressChanged)
//		{
//			TaskHandler[] tasks = new TaskHandler[count];
//			for (int i = 0; i < count; i++)
//			{
//				int a = i;
//				tasks[a] = new TaskHandler((tState) =>
//				{
//					if (tState.CancelRequested == false)
//						body(a, tState);
//					return null;
//				});
//			}
//			ProcessTasksProgressHandler progress = null;
//			if (progressChanged != null)
//			{
//				progress = new ProcessTasksProgressHandler((finished, total) =>
//				{
//					progressChanged((double)finished / (finished + total));
//				});
//			}
//			Parallelization.ProcessTasks(tasks, numberOfThreads, threadState, progress);
//		}

//		public static void For(int count, ForBody body, ThreadState threadState, ProgressChangedHandler progressChanged)
//		{
//			Parallelization.For(count, body, System.Environment.ProcessorCount, threadState, progressChanged);
//		}

//		public static void For(int count, ForBody body, ThreadState threadState)
//		{
//			Parallelization.For(count, body, threadState, null);
//		}

//		public static void For(int count, ForBody body)
//		{
//			ThreadState threadState = new ThreadState();
//			Parallelization.For(count, body, threadState, null);
//		}

//		public static void ProcessTasks(IEnumerable<TaskHandler> tasks, int numberOfThreads, ThreadState threadState, ProcessTasksProgressHandler progressChanged)
//		{
//			Collections.ISynchronizedStack<TaskHandler> taskCollection = new Collections.SynchronizedQueue<TaskHandler>(tasks);
//			Parallelization.ProcessTasks(taskCollection, numberOfThreads, threadState, progressChanged);
//		}

//		public static void ProcessTasks(Collections.ISynchronizedStack<TaskHandler> tasks, int numberOfThreads, ThreadState threadState, ProcessTasksProgressHandler progressChanged)
//		{
//			ThreadStart action = new ThreadStart(()=>
//				{
//					if (numberOfThreads < 1)
//						numberOfThreads = System.Environment.ProcessorCount;

//					WaitHandle[] waitHandles = new WaitHandle[numberOfThreads];
//					SynchronizedInt32 processed = new SynchronizedInt32(0);

//					for (int i = 0; i < numberOfThreads; i++)
//					{
//						waitHandles[i] = new ManualResetEvent(true);
//					}

//					Thread[] threads = new Thread[numberOfThreads];
					
//					for (int i = 0; i < numberOfThreads; i++)
//					{
//						ManualResetEvent waitHandle = (ManualResetEvent)waitHandles[i];
//						threads[i] = new Thread(new ThreadStart(() =>
//						{
//							while (threadState.CancelRequested == false)
//							{
//								if (tasks.Count > 0 && threadState.CancelRequested == false)
//									waitHandle.Reset();

//								while (tasks.Count > 0 && threadState.CancelRequested == false)
//								{
//									threadState.WaitForResumption();

//									TaskHandler task;
//									if (tasks.TryPop(out task) == false)
//										break;
//									IEnumerable<TaskHandler> newTasks = task(threadState);

//									if (newTasks != null)
//										tasks.PushRange(newTasks);

//									if (progressChanged != null)
//									{
//										processed.Increment();
//										progressChanged(processed.Object, tasks.Count);
//									}
//								}
//								waitHandle.Set();

//								if (WaitHandle.WaitAll(waitHandles, 50) == true)
//									break;
//							}
//							waitHandle.Set();
//						}));

//						if (tasks.Count > 0 && threadState.CancelRequested == false)
//						{
//							waitHandle.Reset();
//							threads[i].IsBackground = true;
//							threads[i].Start();
//						}
//					}

//					WaitHandle.WaitAll(waitHandles);
//				});

//			if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)
//			{
//				Thread thread = new Thread(action);
//				thread.Start();
//				thread.Join();
//			}
//			else
//			{
//				action();
//			}
//		}

//		public static void ProcessTasks(IEnumerable<TaskHandler> tasks, ThreadState threadState, ProcessTasksProgressHandler progressChanged)
//		{
//			Parallelization.ProcessTasks(tasks, System.Environment.ProcessorCount, threadState, progressChanged);
//		}

//		public static void ProcessTasks(IEnumerable<TaskHandler> tasks, ThreadState threadState)
//		{
//			Parallelization.ProcessTasks(tasks, System.Environment.ProcessorCount, threadState, null);
//		}

//		public static void ProcessTasks(IEnumerable<TaskHandler> tasks)
//		{
//			ThreadState threadState = new ThreadState();
//			Parallelization.ProcessTasks(tasks, System.Environment.ProcessorCount, threadState, null);
//		}
//	}
//}
